home *** CD-ROM | disk | FTP | other *** search
Wrap
Path: aargh.incubus.sub.org!marc From: marc@aargh.incubus.sub.org (Marc 'Nepomuk' Heuler) Newsgroups: comp.sys.amiga.programmer Subject: Re: Writing shared libraries in assembler Message-ID: <JDiqy*Oza@aargh.incubus.sub.org> Date: Wed, 17 Apr 1996 21:55:57 CET Reply-To: marc@aargh.incubus.sub.org References: <9604162155.AA0035i@etchq.demon.co.uk> Organization: Data Design X-Newsreader: Arn V1.03a In article <9604162155.AA0035i@etchq.demon.co.uk>, MushyPea writes: > I am happy with the idea of writing 100% re-entrant, relocatable code - what > I would like is some assistance on the format of a shared library, including > the library source, and the creation of an _LVO offset file. STRUCTURE mylib,LIB_SIZE ; library base UBYTE mylib_Flags UBYTE mylib_Pad01 APTR mylib_SegList APTR mylib_SysBase APTR mylib_DosBase APTR mylib_ExpansionBase APTR mylib_UtilityBase APTR mylib_GraphicsBase APTR mylib_CiaBase APTR mylib_Status ULONG mylib_RandSeed LABEL mylib_Size SECTION Library,code Dummy moveq #0,d0 rts RomTag dc.w RTC_MATCHWORD dc.l RomTag dc.l .EndCode dc.b RTF_AUTOINIT dc.b _VERSION dc.b NT_LIBRARY dc.b PRIORITY dc.l .Name dc.l .Info dc.l .Init .EndCode .Name NAME dc.b ".library",0 even dc.b "$VER: " .Info NAME dc.b ".library " VERSION dc.b " (" DATE dc.b ")" [copyright info follows] dc.b $d,$a,0 even .Init dc.l mylib_Size dc.l .Func dc.l .Data dc.l Init .Func dc.l Open ;FD: ##base _mylibBase dc.l Close ;FD: ##bias 30 dc.l Expunge ;FD: ##public dc.l Null dc.l mylibRexx ;FD: mylibRexx(rexxmsg)(a0) dc.l mylibRandom ;FD: mylibRandom()() dc.l mylibError ;FD: mylibError(error)(d0) [other function definitions follow] dc.l -1 ;FD: ##end .Data INITBYTE LN_TYPE,NT_LIBRARY INITLONG LN_NAME,.Name INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED INITWORD LIB_VERSION,_VERSION INITWORD LIB_REVISION,_REVISION INITLONG LIB_IDSTRING,.Info dc.l 0 *************************************************** *** Init Library *** *************************************************** *** d0:library a0:seglist *** *************************************************** Init move.l a5,-(sp) move.l d0,a5 ; a5:library move.l a6,mylib_SysBase(a5) move.l a0,mylib_SegList(a5) lea .UtilityName(pc),a1 ; open utility.library moveq #37,d0 CALL OpenLibrary move.l d0,mylib_UtilityBase(a5) beq .Error lea .DosName(pc),a1 ; open dos.library moveq #37,d0 CALL OpenLibrary move.l d0,mylib_DosBase(a5) beq .Error lea .ExpansionName(pc),a1 moveq #37,d0 CALL OpenLibrary move.l d0,mylib_ExpansionBase(a5) beq .Error lea .GraphicsName(pc),a1 ; open graphics.library moveq #37,d0 CALL OpenLibrary move.l d0,mylib_GraphicsBase(a5) beq .Error lea .CiaName(pc),a1 ; open ciab.resource CALL OpenResource move.l d0,mylib_CiaBase(a5) beq .Error [other stuff follows that gets executed whenever the library is fresh loaded into memory] *************************************************** *** Exit *** *************************************************** .Okay move.l a5,d0 .Exit move.l (sp)+,a5 rts .Error bsr Cleanup moveq #0,d0 bra.s .Exit .UtilityName dc.b "utility.library",0 .DosName dc.b "dos.library",0 .ExpansionName dc.b "expansion.library",0 .GraphicsName dc.b "graphics.library",0 .CiaName dc.b "ciab.resource",0 even *************************************************** *** Function: Open() *** *************************************************** *** a6:library d0:version *** *************************************************** Open addq.w #1,LIB_OPENCNT(a6) bclr #LIBB_DELEXP,LIB_FLAGS(a6) move.l a6,d0 rts *************************************************** *** Close() *** *************************************************** *** a6:library *** *************************************************** Close moveq #0,d0 subq.w #1,LIB_OPENCNT(a6) bne.s .Exit btst #LIBB_DELEXP,LIB_FLAGS(a6) beq.s .Exit bsr Expunge .Exit rts *************************************************** *** Expunge() *** *************************************************** *** a6:library *** *************************************************** Expunge movem.l d2/a5-a6,-(sp) move.l a6,a5 tst.w LIB_OPENCNT(a5) bne.s .Delayed bsr Cleanup move.l mylib_SegList(a5),d2 move.l a5,a1 ; remove from library list REMOVE moveq #0,d0 ; free library base move.w LIB_NEGSIZE(a5),d0 move.l a5,a1 sub.l d0,a1 add.w LIB_POSSIZE(a5),d0 CALLEXE FreeMem move.l d2,d0 .Exit movem.l (sp)+,d2/a5-a6 rts .Delayed bset #LIBB_DELEXP,LIB_FLAGS(a5) ; delayed expunge moveq #0,d0 bra.s .Exit *************************************************** *** Cleanup *** *************************************************** Cleanup move.l mylib_ExpansionBase(a5),d0 beq.s .NoExpansion move.l d0,a1 CALLEXE CloseLibrary .NoExpansion move.l mylib_UtilityBase(a5),d0 ; close utility.library beq.s .NoUtility move.l d0,a1 CALLEXE CloseLibrary .NoUtility move.l mylib_DosBase(a5),d0 ; close dos.library beq.s .NoDos move.l d0,a1 CALLEXE CloseLibrary .NoDos move.l mylib_GraphicsBase(a5),d0 ; close graphics.library beq.s .NoGraphics move.l d0,a1 CALLEXE CloseLibrary .NoGraphics rts *************************************************** *** Null() *** *************************************************** Null moveq #0,d0 rts I extract the FD info (see func-table above) by a selfmade ARexx script, and use C='s LVO program to create an _LVO.i file that can be included into Assembly programs that want to use the library functions: rx <"apipe:ssearch src:mylib/mylib.s *";FD: *" cs nonum" >src:mylib/mylib_lib.fd "do while ~eof(stdin) ; line = readln(stdin) ; if line ~= '' then say delstr(line,1,pos(';FD: ',line)+4) ; end" copy src:mylib/mylib_lib.fd fd: rx <"apipe:lvo mylib" >src:mylib/mylib_lvo.i "do while ~eof(stdin) ; line = readln(stdin) ; if line = '' then iterate ; parse var line with ' $' dummy ' ' offset ' ' name '()' ; say '_LVO'||name '=' offset ; end > Does anybody have any suggestions or advice on writing libraries? I don't > particularly want to have to spend large quantities of money on the RKMs at > the moment, although I will eventually invest in them. You should buy them now! Programming a library is not the only thing that can be done wrong.